package chagine.core.util;

import chagine.core.ErrorCode;
import chagine.core.exception.SeeingRuntimeException;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.apache.commons.lang.StringUtils;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Assert {

    // 匹配规则 参数名(响应的信息)
    private static final Pattern PATTERN_INFO = Pattern.compile("\\(+.*\\)*$");
    // 异常模版
    private static final String PARAMS_ERROR_TEMPLATE = "参数 %s 为空";

    /**
     * 业务运行异常
     */
    public static void error(boolean status, String code, String message) {
        if (status) {
            throw new SeeingRuntimeException(code, message);
        }
    }

    /**
     * 抛出空参数的业务异常
     */
    public static void throwEmptyParamMessage(Object object, String paramsName) {
        String paramsValue = String.format(PARAMS_ERROR_TEMPLATE, paramsName);
        String code = ErrorCode.ILLEGALARGUMENT_EXCEPTION;
        error(object == null, code, paramsValue);
        if (object instanceof String) {
            error(StringUtils.isBlank((String) object), code, paramsValue);
        } else if (object instanceof Collection) {
            error(((Collection) object).isEmpty(), code, paramsValue);
        }
    }

    /**
     * 检查对象为空
     */
    private static String checkObjectIsNull(Object object, String message) {
        error(object == null, ErrorCode.ILLEGALARGUMENT_EXCEPTION, message);
        if (object instanceof String) {
            String stringInput = (String) object;
            error(StringUtils.isBlank(stringInput), ErrorCode.ILLEGALARGUMENT_EXCEPTION, message + "不能为空");
            return stringInput;
        }
        return null;
    }

    /**
     * 检查字符串对象为空或者超过长度限制
     */
    public static void checkObjectIsNullOrTooLong(Object object, int maxLength, String message) {
        String stringInput = checkObjectIsNull(object, message);
        error(stringInput != null && stringInput.length() > maxLength, ErrorCode.ILLEGALARGUMENT_EXCEPTION, "[" + message + "]-不能超过[" + maxLength + "]个字符");
    }

    /**
     * 检查对象中所有的字段是否为空
     *
     * @param object         被检查的属性
     * @param jsonAnnotation 是否检查JsonProperty的主机
     */
    public static void checkObjectAllParamIsNull(Object object, boolean jsonAnnotation) {
        // 判断属性是否为空
        Class<?> clazz = object.getClass();
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            field.setAccessible(true);
            String name = field.getName();
            if (jsonAnnotation) {
                JsonProperty annotation = field.getAnnotation(JsonProperty.class);
                if (annotation != null) {
                    String value = annotation.value();
                    checkParamsIsEmpty(value, field, object);
                } else {
                    checkParamsIsEmpty(name, field, object);
                }
            } else {
                checkParamsIsEmpty(name, field, object);
            }
        }

    }

    /**
     * 检查对象中某个字段是否为空
     *
     * @param object         被检查的属性
     * @param jsonAnnotation 是否检查JsonProperty的主机
     * @param paramsNames    被检查参数
     */
    public static void checkObjectParamIsNull(Object object, boolean jsonAnnotation, String... paramsNames) {
        // 设置查询参数
        List<String> paramsNameList = new ArrayList<>();
        List<String> paramsReplaceList = new ArrayList<>();
        for (String param : paramsNames) {
            if (StringUtils.isNotBlank(param)) {
                Matcher matcher = PATTERN_INFO.matcher(param);
                boolean messageExist = matcher.find();
                if (messageExist) {
                    String group = matcher.group();
                    param = param.substring(0, param.indexOf(group));
                    paramsNameList.add(param);
                    // 处理group
                    group = group.substring(1);
                    if (group.endsWith(")")) {
                        group = group.substring(0, group.length() - 1);
                    }
                    paramsReplaceList.add(group);
                } else {
                    paramsNameList.add(param);
                    paramsReplaceList.add("");
                }
            }
        }
        if (paramsNameList.isEmpty()) {
            return;
        }
        // 判断属性是否为空
        Class<?> clazz = object.getClass();

        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            field.setAccessible(true);
            String name = field.getName();
            if (jsonAnnotation) {
                JsonProperty annotation = field.getAnnotation(JsonProperty.class);
                if (annotation != null) {
                    String value = annotation.value();
                    checkParamsIsEmpty(paramsNameList, paramsReplaceList, value, field, object);
                } else {
                    checkParamsIsEmpty(paramsNameList, paramsReplaceList, name, field, object);
                }
            } else {
                checkParamsIsEmpty(paramsNameList, paramsReplaceList, name, field, object);
            }
        }
    }

    private static void checkParamsIsEmpty(String paramName, Field field, Object object) {
        try {
            Object fieldValue = field.get(object);
            if (fieldValue instanceof String) {
                error(StringUtils.isBlank((String) fieldValue), ErrorCode.ILLEGALARGUMENT_EXCEPTION, replaceErrorMsg(false, paramName));
            } else if (fieldValue instanceof Collection) {
                error(((Collection) fieldValue).isEmpty(), ErrorCode.ILLEGALARGUMENT_EXCEPTION, replaceErrorMsg(false, paramName));
            } else {
                error(fieldValue == null, ErrorCode.ILLEGALARGUMENT_EXCEPTION, replaceErrorMsg(false, paramName));
            }
        } catch (IllegalAccessException ignore) {
            error(true, ErrorCode.UNKNOWN_EXCEPTION, "java field error");
        }
    }

    private static void checkParamsIsEmpty(List<String> paramsNameList, List<String> paramsReplaceList, String paramName, Field field, Object object) {
        if (paramsNameList.contains(paramName)) {
            try {
                // 如果存在则查询第几个
                int index = paramsNameList.indexOf(paramName);
                String replaceName = paramsReplaceList.get(index);
                // 是否替换
                boolean replaceStatus = StringUtils.isNotBlank(replaceName);
                replaceName = replaceStatus ? replaceName : paramName;

                Object fieldValue = field.get(object);
                if (fieldValue instanceof String) {
                    error(StringUtils.isBlank((String) fieldValue), ErrorCode.ILLEGALARGUMENT_EXCEPTION, replaceErrorMsg(replaceStatus, replaceName));
                } else if (fieldValue instanceof Collection) {
                    error(((Collection) fieldValue).isEmpty(), ErrorCode.ILLEGALARGUMENT_EXCEPTION, replaceErrorMsg(replaceStatus, replaceName));
                } else {
                    error(fieldValue == null, ErrorCode.ILLEGALARGUMENT_EXCEPTION, replaceErrorMsg(replaceStatus, replaceName));
                }
            } catch (IllegalAccessException ignore) {
                error(true, ErrorCode.UNKNOWN_EXCEPTION, "java field error");
            }
        }
    }

    private static String replaceErrorMsg(boolean replaceStatus, String replaceValue) {
        if (replaceStatus) {
            // 替换
            return replaceValue;
        } else {
            // 不替换
            return String.format(PARAMS_ERROR_TEMPLATE, replaceValue);
        }
    }


}
